﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using MySqlWrapper;
using MySql.Data.MySqlClient;
using System.Text.RegularExpressions;
using System.Security.Cryptography;

namespace Teenus
{

    public class Service : IService
    {

        #region kohvikud
        public List<EntityKohvik> getEntityKohvikList()
        {
            Program.writeToLog("getEntityKohvikList()");

            List<EntityKohvik> kohvikud = Cache.getKohvikList();
            if (kohvikud != null)
                return kohvikud;

            kohvikud = new List<EntityKohvik>();
            Database db = new Database();

            MySqlDataReader reader = db.sendQuery("SELECT * FROM kohvik");
            if (reader == null)
            {
                db.CloseConnection();
                return null;
            }

            if (!reader.HasRows)
            {
                reader.Close();
                db.CloseConnection();
                return null;
            }

            while (reader.Read())
            {
                kohvikud.Add(new EntityKohvik()
                {
                    Kohvik_ID = (int)reader.GetValue(0),
                    Nimi = (String)reader.GetValue(1),
                    Latitude = (String)reader.GetValue(2),
                    Longitude = (String)reader.GetValue(3),
                    Riik = (String)reader.GetValue(4),
                    Maakond = (String)reader.GetValue(5),
                    LinnVald = (String)reader.GetValue(6),
                    Indeks = (int)reader.GetValue(7),
                    Tanav = (String)reader.GetValue(8),
                    Maja = (String)reader.GetValue(9),
                });
            }
            reader.Close();

            db.CloseConnection();
            Cache.setKohvikud(kohvikud);
            return kohvikud;
        }


        public EntityKohvik getEntityKohvikById(int id)
        {
            Program.writeToLog("getEntityKohvikList(" + id + ")");

            EntityKohvik kohvik = Cache.getKohvikByID(id);
            if (kohvik != null)
                return kohvik;

            Database db = new Database();
            MySqlDataReader reader = db.sendQuery("SELECT * FROM kohvik WHERE kohvik_ID=" + id);
            kohvik = new EntityKohvik();
            if (reader == null)
            {
                db.CloseConnection();
                return null;
            }

            if (!reader.HasRows)
            {
                reader.Close();
                db.CloseConnection();
                return null;
            }

            while (reader.Read())
            {
                kohvik.Kohvik_ID = (int)reader.GetValue(0);
                kohvik.Nimi = (String)reader.GetValue(1);
                kohvik.Latitude = (String)reader.GetValue(2);
                kohvik.Longitude = (String)reader.GetValue(3);
                kohvik.Riik = (String)reader.GetValue(4);
                kohvik.Maakond = (String)reader.GetValue(5);
                kohvik.LinnVald = (String)reader.GetValue(6);
                kohvik.Indeks = (int)reader.GetValue(7);
                kohvik.Tanav = (String)reader.GetValue(8);
                kohvik.Maja = (String)reader.GetValue(9);
            }
            reader.Close();

            db.CloseConnection();
            return kohvik;
        }


        public string getKohvikuKirjeldus(string id)
        {
            string result = string.Empty;

            Database db = new Database();
            MySqlDataReader reader = db.sendQuery("SELECT kirjeldus FROM kohvik WHERE kohvik_ID=" + id);

            reader.Read();

            result = reader["kirjeldus"].ToString();

            reader.Close();

            return result;

        }


        public int newKohvikuKirjeldus(string kirjeldus, string id)
        {
            int vastus = new Database().sendNonQuery(String.Format("UPDATE kohvik SET kirjeldus='{0}' WHERE kohvik_ID={1}", kirjeldus, id));
            if(vastus > 0) {
                Cache.setKohvikListNull();
            }
            return vastus;
        }


        public int lisaUusKohvik(EntityKohvik k) {
           // return 1;
           // return new Database().sendNonQuery(String.Format("insert into kohvik(nimi,latitude,longitude,riik,maakond,linnVald,indeks,tanav,maja,kirjeldus) values('{0}','{1}','{2}','{3}','{4}','{5}','{6}','{7','{8}','{9}')", k.Nimi, k.Latitude, k.Longitude, k.Riik, k.LinnVald, k.Indeks, k.Tanav, k.Maja, k.Kirjeldus));
            Database db = new Database();
            String query = "INSERT INTO kohvik(nimi,latitude,longitude,riik,maakond,linnVald,indeks,tanav,maja,kirjeldus) VALUES(?nimi,?latitude,?longitude,?riik,?maakond,?linnVald,?indeks,?tanav,?maja,?kirjeldus)";
            MySqlParameter[] parameters = new MySqlParameter[10];
            parameters[0] = new MySqlParameter("?nimi", k.Nimi);
            parameters[1] = new MySqlParameter("?latitude", k.Latitude);
            parameters[2] = new MySqlParameter("?longitude", k.Longitude);
            parameters[3] = new MySqlParameter("?riik", k.Riik);
            parameters[4] = new MySqlParameter("?maakond", k.Maakond);
            parameters[5] = new MySqlParameter("?linnVald", k.LinnVald);
            parameters[6] = new MySqlParameter("?indeks", k.Indeks);
            parameters[7] = new MySqlParameter("?tanav", k.Tanav);
            parameters[8] = new MySqlParameter("?maja", k.Maja);
            parameters[9] = new MySqlParameter("?kirjeldus", k.Kirjeldus);
            
            int lastInsertedUniqueId = db.parameterizedInsert(query, parameters);
            if (lastInsertedUniqueId < 1)
                Program.writeToLog("FAILED: lisaUusKohvik()");

            Cache.setKohvikListNull();
            return lastInsertedUniqueId;      
        }


        #endregion


        #region toidud
        public List<EntityKaup> getAllItems()
        {
            Program.writeToLog("getAllItems()");

            List<EntityKaup> kaubad = Cache.getKaupList();
            if (kaubad != null)
                return kaubad;

            kaubad = new List<EntityKaup>();
            Database db = new Database();
            MySqlDataReader reader = db.sendQuery("SELECT t1.kaup_ID,t1.kohvik_ID,t1.kat_ID,t1.nimetus,t2.olemine_ID,t2.kuupaev,t3.kat_ID,t3.nimetus FROM kaup t1,menyys_olemine t2,kategooria t3 WHERE t2.kaup_ID=t1.kaup_ID AND t3.kat_ID=t1.kat_ID");

            if (reader == null)
            {
                db.CloseConnection();
                return null;
            }
            if (!reader.HasRows)
            {
                reader.Close();
                db.CloseConnection();
                return null;
            }

            while (reader.Read())
            {
                kaubad.Add(new EntityKaup
                {
                    ID = (int)reader.GetValue(0),
                    KohvikID = (int)reader.GetValue(1),
                    Kat_ID = (int)reader.GetValue(2),
                    Nimetus = (String)reader.GetValue(3),
                    Olemine_ID = (int)reader.GetValue(4),
                    Date = (DateTime)reader.GetValue(5),
                    Kategooria = new EntityKategooria
                    {
                        Kat_ID = (int)reader.GetValue(6),
                        Nimetus = (String)reader.GetValue(7),
                    }
                });
            }
            reader.Close();

            foreach (EntityKaup k in kaubad)
            {
                k.portsjonid = getEntityPortsList(k.Olemine_ID, db);
                k.soodukad = getEntitySoodustusList(k.Olemine_ID, db);
            }

            db.CloseConnection();
            Cache.setKaubad(kaubad);
            return kaubad;
        }


        /// <summary>
        /// hangib kaubad koos nime, ID, kohviku ID, kat_IDga
        /// </summary>
        /// <returns></returns>
        public List<EntityKaup> getAllItemNames() {
            Program.writeToLog("getAllItemNames()");

            List<EntityKaup> kaubad = Cache.getKaupListSimple();
            if (kaubad != null)
                return kaubad;

            kaubad = new List<EntityKaup>();
            Database db = new Database();
            MySqlDataReader reader = db.sendQuery("SELECT kaup_ID,kohvik_ID,kat_ID,nimetus FROM kaup");

            if (reader == null) {
                db.CloseConnection();
                return null;
            }
            if (!reader.HasRows) {
                reader.Close();
                db.CloseConnection();
                return null;
            }

            while (reader.Read()) {
                kaubad.Add(new EntityKaup {
                    ID = (int)reader.GetValue(0),
                    KohvikID = (int)reader.GetValue(1),
                    Kat_ID = (int)reader.GetValue(2),
                    Nimetus = (String)reader.GetValue(3)
                });
            }
            reader.Close();

            db.CloseConnection();
            Cache.setKaubadSimple(kaubad);
            return kaubad;
        }


        public List<EntityKaup> getItemData(int kohvikID, string date)
        {
            Program.writeToLog("getItemData(" + kohvikID + "," + date + ")");

            Database db = new Database();
            MySqlDataReader reader = db.sendQuery("SELECT t1.kaup_ID,t1.kohvik_ID,t1.kat_ID,t1.nimetus,t2.olemine_ID,t2.kuupaev,t3.kat_ID,t3.nimetus FROM kaup t1,menyys_olemine t2,kategooria t3 WHERE t1.kohvik_ID=" + kohvikID + " AND t2.kaup_ID=t1.kaup_ID AND t2.kuupaev='" + date + "' AND t3.kat_ID=t1.kat_ID");

            if (reader == null)
            {
                db.CloseConnection();
                return null;
            }
            if (!reader.HasRows)
            {
                reader.Close();
                db.CloseConnection();
                return null;
            }

            List<EntityKaup> toidud = new List<EntityKaup>();
            while (reader.Read())
            {
                toidud.Add(new EntityKaup
                {
                    ID = (int)reader.GetValue(0),
                    KohvikID = (int)reader.GetValue(1),
                    Kat_ID = (int)reader.GetValue(2),
                    Nimetus = (String)reader.GetValue(3),
                    Olemine_ID = (int)reader.GetValue(4),
                    Date = (DateTime)reader.GetValue(5),
                    Kategooria = new EntityKategooria
                    {
                        Kat_ID = (int)reader.GetValue(6),
                        Nimetus = (String)reader.GetValue(7),
                    }
                });
            }
            reader.Close();

            foreach (EntityKaup toit in toidud)
            {
                toit.portsjonid = getEntityPortsList(toit.Olemine_ID, db);
                toit.soodukad = getEntitySoodustusList(toit.Olemine_ID, db);
            }

            db.CloseConnection();
            return toidud;
        }


        public EntityKaup getItemByOlemineId(int olemineID)
        {
            Program.writeToLog("getItemByOlemineId(" + olemineID + ")");

            Database db = new Database();
            MySqlDataReader reader = db.sendQuery("SELECT t1.kaup_ID,t1.kohvik_ID,t1.kat_ID,t1.nimetus,t2.olemine_ID,t2.kuupaev,t3.kat_ID,t3.nimetus FROM kaup t1,menyys_olemine t2,kategooria t3 WHERE t2.olemine_ID=" + olemineID + " AND t2.kaup_ID=t1.kaup_ID AND t3.kat_ID=t1.kat_ID");

            if (reader == null)
            {
                db.CloseConnection();
                return null;
            }
            if (!reader.HasRows)
            {
                reader.Close();
                db.CloseConnection();
                return null;
            }

            EntityKaup kaup;
            reader.Read();
            kaup = new EntityKaup
            {
                ID = (int)reader.GetValue(0),
                KohvikID = (int)reader.GetValue(1),
                Kat_ID = (int)reader.GetValue(2),
                Nimetus = (String)reader.GetValue(3),
                Olemine_ID = (int)reader.GetValue(4),
                Date = (DateTime)reader.GetValue(5),
                Kategooria = new EntityKategooria
                {
                    Kat_ID = (int)reader.GetValue(6),
                    Nimetus = (String)reader.GetValue(7),
                }
            };
            reader.Close();

            kaup.portsjonid = getEntityPortsList(kaup.Olemine_ID, db);
            kaup.soodukad = getEntitySoodustusList(kaup.Olemine_ID, db);

            db.CloseConnection();
            return kaup;
        }


        /// <summary>
        /// hangib kõik kaupade kategooriad
        /// </summary>
        /// <returns></returns>
        public List<EntityKategooria> getAllCategories() {
            Program.writeToLog("getAllCategories()");

            List<EntityKategooria> kategooriad = Cache.getKatList();
            if (kategooriad != null)
                return kategooriad;

            kategooriad = new List<EntityKategooria>();
            Database db = new Database();
            MySqlDataReader reader = db.sendQuery("SELECT * FROM kategooria");

            if (reader == null) {
                db.CloseConnection();
                return null;
            }
            if (!reader.HasRows) {
                reader.Close();
                db.CloseConnection();
                return null;
            }

            while (reader.Read()) {
                kategooriad.Add(new EntityKategooria {
                    Kat_ID = (int)reader.GetValue(0),
                    Nimetus = (string)reader.GetValue(1)
                });
            }
            reader.Close();

            db.CloseConnection();
            Cache.setKategooriad(kategooriad);
            return kategooriad;
        }


        private List<EntityPorts> getEntityPortsList(int olemine_id, Database db)
        {
            MySqlDataReader reader = db.sendQuery("SELECT t2.ports_ID, t2.nimetus, t2.saadaval, t2.hind, t2.valuuta_ID FROM portsjonid t1,ports t2 WHERE t1.olemine_ID=" + olemine_id + " AND t2.ports_ID=t1.ports_ID");

            if (reader == null)
            {
                return null;
            }
            if (!reader.HasRows)
            {
                reader.Close();
                return null;
            }

            List<EntityPorts> portsud = new List<EntityPorts>(3);
            while (reader.Read())
            {
                try
                {
                    portsud.Add(new EntityPorts
                    {
                        Ports_ID = (int)reader.GetValue(0),
                        Nimetus = (String)reader.GetValue(1),
                        Saadaval = intToBoolean((SByte)reader.GetValue(2)),
                        Hind = Double.Parse((String)reader.GetValue(3), new System.Globalization.CultureInfo("en-US")),
                        Valuuta_ID = (int)reader.GetValue(4)
                    });
                }
                catch (Exception)
                {
                    //andmebaasis olev väärtus pole parsitav
                    Program.writeToLog("FAILED parsing: loePortsud(" + olemine_id + ")");
                }
            }   //END while
            reader.Close();
            return portsud;
        }


        private List<EntitySoodustus> getEntitySoodustusList(int olemine_ID, Database db)
        {
            MySqlDataReader reader = db.sendQuery("SELECT t2.soodustus_ID,t2.liik,t2.suurus,t2.yhik FROM soodustuse_rida t1,soodustus t2 WHERE t1.olemine_ID=" + olemine_ID + " AND t2.soodustus_ID=t1.soodustus_ID");

            if (reader == null)
            {
                return null;
            }
            if (!reader.HasRows)
            {
                reader.Close();
                return null;
            }

            List<EntitySoodustus> soodukad = new List<EntitySoodustus>(3);
            while (reader.Read())
            {
                try
                {
                    soodukad.Add(new EntitySoodustus
                    {
                        Id = (int)reader.GetValue(0),
                        Liik = (String)reader.GetValue(1),
                        Suurus = Double.Parse((String)reader.GetValue(2), new System.Globalization.CultureInfo("en-US")),
                        Yhik = (String)reader.GetValue(3)
                    });
                }
                catch (Exception)
                {
                    //andmebaasis olev väärtus pole parsitav
                    Program.writeToLog("FAILED parsing: loeSoodukad(" + olemine_ID + ")");
                }
            }   //END while
            reader.Close();
            return soodukad;
        }


        public Boolean insertItem(int kohvikID, String kategooria, String nimetus, String kuupaev, List<EntityPorts> portsud, List<EntitySoodustus> soodukad)
        {
            Program.writeToLog("insertItem(" + kohvikID + "," + kategooria + "," + nimetus + "," + kuupaev + "," + portsud.Count + "," + soodukad.Count + ")");

            Database db = new Database();

            int kat_ID = getCategory(db, kategooria);
            if (kat_ID == 0)
            {
                kat_ID = insertCategory(db, kategooria);    //kui antud nimega kategooriat ei ole olemas, siis tuleb see tekitada
                if (kat_ID == -1)
                {
                    return false;
                }
            }
            else if (kat_ID == -1)
            {
                return false;
            }

            int kaup_ID = getEntityKaupId(db, kohvikID, kat_ID, nimetus);
            if (kaup_ID == 0)
            {
                kaup_ID = insertEntityKaup(db, kohvikID, kat_ID, nimetus);   //kui antud nimega kaupa ei ole olemas, siis tuleb see tekitada
                if (kaup_ID == -1)
                {
                    return false;
                }
            }
            else if (kaup_ID == -1)
            {
                return false;
            }

            int olemine_ID = insertIntoMenu(db, kaup_ID, kuupaev);
            if (olemine_ID == -1)
            {
                return false;
            }

            foreach (EntityPorts ports in portsud)
            {
                int ports_ID = insertEntityPorts(db, ports.Nimetus, ports.Saadaval, ports.Hind, ports.Valuuta_ID);   //kui antud nimega portsu ei ole olemas, siis tuleb see tekitada
                if (ports_ID < 1)
                {
                    continue;
                }

                int portsjonid_ID = insertIntoPortsjonid(db, olemine_ID, ports_ID);
                if (portsjonid_ID == -1)
                {
                }
            }

            foreach (EntitySoodustus soodukas in soodukad)
            {
                int soodustus_ID = getEntitySoodustusId(db, soodukas.Liik, soodukas.Suurus, soodukas.Yhik);
                if (soodustus_ID == 0)
                {
                    soodustus_ID = insertEntitySoodustus(db, soodukas.Liik, soodukas.Suurus, soodukas.Yhik);
                    if (soodustus_ID == -1)
                    {
                        continue;
                    }
                    //            
                }
                else if (soodustus_ID == -1)
                {
                    continue;
                }

                int soodustus_rida_ID = insertIntoSoodustuseRida(db, olemine_ID, soodustus_ID);
            }   //END foreach soodukad

            Cache.setKaupListNull();

            return true;
        }   //END insertItem()


        /// <summary>
        /// Võimaldab menüüsse sisestatud kauba andmeid muuta või selle teisele päevale üle viia.
        /// </summary>
        /// <param name="olemineID"></param>
        /// <param name="kategooria"></param>
        /// <param name="nimetus"></param>
        /// <param name="kuupaev"></param>
        /// <param name="portsud">Portsu juures peavad olema täidetud kõik väljad peale ID</param>
        /// <param name="soodukad">Sooduka juures peavad olema täidetud kõik väljad peale ID</param>
        /// <returns></returns>
        public Boolean editItem(int olemineID, String kategooria, String nimetus, String kuupaev, List<EntityPorts> portsud, List<EntitySoodustus> soodukad)
        {
            Program.writeToLog("editItem(" + olemineID + "," + kategooria + "," + nimetus + "," + kuupaev + "," + portsud.Count + "," + soodukad.Count + ")");

            if (olemineID < 1 || kategooria == null || nimetus == null)
            {
                return false;
            }

            DateTime d;
            if (!DateTime.TryParse(kuupaev, out d))
            {
                return false;
            }

            Database db = new Database();

            EntityKaup kaup = getItemByOlemineId(olemineID);    //vaja läheb kohviku ID ja kauba ID
            if (kaup == null)
            {
                return false;
            }

            String olemineDate = getOlemineDate(db, olemineID);
            if (olemineDate == null)
            {
                return false;
            }

            //kui kasutaja soovib seda toitu liigutada teisele päevale, siis tuleb see sellelt päevalt eemaldada ja uuesti lisada teisele päevale            
            if (!olemineDate.Equals(kuupaev))
            {
                if (removeFromMenu(db, olemineID) < 1)
                {
                    return false;
                }
                return insertItem(kaup.KohvikID, kategooria, nimetus, kuupaev, portsud, soodukad);
            }


            EntityKategooria kat = getCategory(db, kaup.ID);
            if (kat == null)
            {
                return false;
            }
            if (!kat.Nimetus.Equals(kategooria))
            {
                if (removeFromMenu(db, olemineID) < 1)
                {
                    return false;
                }
                return insertItem(kaup.KohvikID, kategooria, nimetus, kuupaev, portsud, soodukad);
            }

            if (!kaup.Nimetus.Equals(nimetus))
            {
                if (removeFromMenu(db, olemineID) < 1)
                {
                    return false;
                }
                return insertItem(kaup.KohvikID, kategooria, nimetus, kuupaev, portsud, soodukad);
            }

            //järgnevalt portsude osa:
            List<EntityPorts> pList = getEntityPortsList(olemineID, db);
            Boolean[] bArr;
            if (pList != null)
            {
                bArr = new Boolean[pList.Count];
            }
            else
            {
                bArr = null;    //kui pList on tühi, siis pole ka booleanide arrayd vaja
            }

            foreach (EntityPorts ports in portsud)
            {
                Boolean leitiVaste = false;

                if (pList != null)
                {                         //kui eelnevalt pole toiduga seostatud portse, siis ei tohi vasteid otsida
                    for (int i = 0; i < pList.Count; i++)
                    {
                        if (ports.EqualsWithoutID(pList[i]))
                        {
                            bArr[i] = true;
                            leitiVaste = true;
                        }
                    }
                }

                //kui otsitavat kirjet ei ole juba toiduga seostatud, siis tuleb see lisada
                if (!leitiVaste)
                {
                    int id = insertEntityPorts(db, ports.Nimetus, ports.Saadaval, ports.Hind, ports.Valuuta_ID);
                    if (id < 1)
                    {
                        return false;
                    }
                    if (insertIntoPortsjonid(db, olemineID, id) < 1)
                    {
                        return false;
                    }
                }
            }

            //kustutame nende portsude kirjed, mida kasutaja ei soovi enam
            if (pList != null)
            {
                for (int i = 0; i < pList.Count; i++)
                {
                    if (!bArr[i])
                    {
                        if (removeFromPortsud(db, pList[i].Ports_ID) < 1)
                        {
                            return false;
                        }
                        if (deleteEntityPorts(db, pList[i].Ports_ID) < 1)
                        {
                            return false;
                        }
                    }
                }
            }

            //järgnevalt soodustuste osa:
            List<EntitySoodustus> sList = getEntitySoodustusList(olemineID, db);
            Boolean[] sArr;
            if (sList != null)
            {
                sArr = new Boolean[sList.Count];
            }
            else
            {
                sArr = null;
            }

            foreach (EntitySoodustus soodukas in soodukad)
            {
                Boolean leitiVaste = false;

                if (sList != null)
                {
                    for (int i = 0; i < sList.Count; i++)
                    {
                        if (soodukas.EqualsWithoutId(sList[i]))
                        {
                            sArr[i] = true;
                            leitiVaste = true;
                        }
                    }
                }

                if (!leitiVaste)
                {
                    int soodustus_ID = getEntitySoodustusId(db, soodukas.Liik, soodukas.Suurus, soodukas.Yhik);
                    if (soodustus_ID == 0)
                    {
                        soodustus_ID = insertEntitySoodustus(db, soodukas.Liik, soodukas.Suurus, soodukas.Yhik);
                        if (soodustus_ID < 1)
                        {
                            return false;
                        }
                    }
                    else if (soodustus_ID == -1)
                    {
                        return false;
                    }

                    int soodustus_rida_ID = insertIntoSoodustuseRida(db, olemineID, soodustus_ID);
                    if (soodustus_rida_ID < 1)
                    {
                        return false;
                    }

                }
            }

            //kustutame seosed nende olemiste ja portsude vahel, mida kasutaja ei soovi enam
            if (sList != null)
            {
                for (int i = 0; i < sList.Count; i++)
                {
                    if (!sArr[i])
                    {
                        if (removeFromSoodustuseRida(db, olemineID, sList[i].Id) < 1)
                        {
                            return false;
                        }
                    }
                }
            }

            Cache.setKaupListNull();

            return true;
        }   //END editItem()


        public Boolean deleteItem(int itemID, String kuupaev)
        {
            Program.writeToLog("deleteItem(" + itemID + "," + kuupaev + ")");

            Database db = new Database();

            int olemineID = getOlemine(db, itemID, kuupaev);
            if (olemineID < 1)
            {
                return false;
            }

            if (removeFromMenu(db, olemineID) < 1)
            {
                return false;
            }

            //TODO: kustutada ka portsud, et pahna tekkimist vältida

            Cache.setKaupListNull();

            return true;
        }   //END deleteItem()



        public Boolean deleteItemByOlemineId(int olemineID)
        {
            Program.writeToLog("deleteItem(" + olemineID + ")");

            if (olemineID < 1)
            {
                return false;
            }

            Database db = new Database();

            if (removeFromMenu(db, olemineID) < 1)
            {
                return false;
            }

            //TODO: kustutada ka portsud, et pahna tekkimist vältida

            Cache.setKaupListNull();

            return true;
        }   //END deleteItem()


        private int getCategory(Database db, string kategooria)
        {
            MySqlDataReader reader = db.sendQuery("SELECT DISTINCT kat_ID FROM kategooria WHERE nimetus='" + kategooria + "'");

            if (reader == null)
            {
                Program.writeToLog("FAILED: getCategory(" + kategooria + ")");
                return -1;          //tekkis mingi viga
            }
            if (!reader.HasRows)
            {
                reader.Close();
                return 0;           //sellist kirjet ei leidu
            }

            int id;
            reader.Read();
            try
            {
                id = (int)reader.GetValue(0);
            }
            catch (Exception e)
            {
                Program.writeToLog("FAILED: getCategory(" + kategooria + "): " + e.ToString());
                id = -1;
            }
            reader.Close();

            return id;
        }   //END getCategory()


        private EntityKategooria getCategory(Database db, int kaupID)
        {
            MySqlDataReader reader = db.sendQuery("SELECT t1.kat_ID,t1.nimetus FROM kategooria t1,kaup t2 WHERE t2.kaup_ID=" + kaupID + " AND t2.kat_ID=t1.kat_ID");

            if (reader == null)
            {
                return null;          //tekkis mingi viga
            }
            if (!reader.HasRows)
            {
                reader.Close();
                return null;           //sellist kirjet ei leidu
            }

            EntityKategooria kat;
            reader.Read();
            try
            {
                kat = new EntityKategooria
                {
                    Kat_ID = (int)reader.GetValue(0),
                    Nimetus = (string)reader.GetValue(1)
                };
            }
            catch (Exception e)
            {
                Program.writeToLog("FAILED: getCategory(" + kaupID + "): " + e.ToString());
                kat = null;
            }
            reader.Close();

            return kat;
        }   //END getCategory()


        private int getEntityKaupId(Database db, int kohvikID, int kat_ID, string nimetus)
        {
            MySqlDataReader reader = db.sendQuery("SELECT DISTINCT kaup_ID FROM kaup WHERE kohvik_ID=" + kohvikID + " AND kat_ID=" + kat_ID + " AND nimetus='" + nimetus + "'");

            if (reader == null)
            {
                Program.writeToLog("FAILED: getMerchandise(" + kohvikID + "," + kat_ID + "," + nimetus + ")");
                return -1;          //tekkis mingi viga
            }
            if (!reader.HasRows)
            {
                reader.Close();
                return 0;           //sellist kirjet ei leidu
            }

            int id;
            reader.Read();
            try
            {
                id = (int)reader.GetValue(0);
            }
            catch (Exception e)
            {
                Program.writeToLog("FAILED: getMerchandise(" + kohvikID + "," + kat_ID + "," + nimetus + "): " + e.ToString());
                id = -1;
            }
            reader.Close();

            return id;
        }


        private EntityKaup getEntityKaupById(Database db, int kaupID)
        {
            MySqlDataReader reader = db.sendQuery("SELECT * FROM kaup WHERE kaup_ID=" + kaupID);

            if (reader == null)
            {
                Program.writeToLog("FAILED: getMerchandise(" + kaupID + ")");
                return null;          //tekkis mingi viga
            }
            if (!reader.HasRows)
            {
                reader.Close();
                return null;           //sellist kirjet ei leidu
            }

            EntityKaup kaup;
            reader.Read();
            try
            {
                kaup = new EntityKaup
                {
                    ID = (int)reader.GetValue(0),
                    KohvikID = (int)reader.GetValue(1),
                    Kat_ID = (int)reader.GetValue(2),
                    Nimetus = (string)reader.GetValue(3)
                };
            }
            catch (Exception e)
            {
                Program.writeToLog("FAILED: getMerchandise(" + kaupID + "): " + e.ToString());
                kaup = null;
            }
            reader.Close();

            return kaup;
        }


        private int getOlemine(Database db, int itemID, string kuupaev)
        {
            MySqlDataReader reader = db.sendQuery("SELECT olemine_ID FROM menyys_olemine WHERE kaup_ID=" + itemID + " AND kuupaev='" + kuupaev + "'");

            if (reader == null)
            {
                Program.writeToLog("FAILED: getOlemine(" + itemID + "," + kuupaev + "): query error");
                return -1;          //tekkis mingi viga
            }
            if (!reader.HasRows)
            {
                reader.Close();
                return 0;           //sellist kirjet ei leidu
            }

            int id;
            reader.Read();
            try
            {
                id = (int)reader.GetValue(0);
            }
            catch (Exception e)
            {
                Program.writeToLog("FAILED: getOlemine(" + itemID + "," + kuupaev + "): " + e.ToString());
                id = -1;
            }
            reader.Close();

            return id;
        }


        private String getOlemineDate(Database db, int olemineID)
        {
            MySqlDataReader reader = db.sendQuery("SELECT kuupaev FROM menyys_olemine WHERE olemine_ID=" + olemineID + "");

            if (reader == null)
            {
                Program.writeToLog("FAILED: getOlemineDate(" + olemineID + "): query error");
                return null;          //tekkis mingi viga
            }
            if (!reader.HasRows)
            {
                reader.Close();
                return null;           //sellist kirjet ei leidu
            }

            String date;
            reader.Read();
            try
            {
                date = ((DateTime)reader.GetValue(0)).ToString("yyyy-MM-dd");
            }
            catch (Exception e)
            {
                Program.writeToLog("FAILED: getOlemineDate(" + olemineID + "): " + e.ToString());
                date = null;
            }
            reader.Close();

            return date;
        }


        private int removeFromMenu(Database db, int olemineID)
        {
            String query = "DELETE FROM menyys_olemine WHERE olemine_ID=" + olemineID;
            int affectedrows = db.sendNonQuery(query);
            if (affectedrows < 1)
            {
                Program.writeToLog("FAILED: removeFromMenu(" + olemineID + ")");
            }

            return affectedrows;
        }


        private int getEntityPortsId(Database db, string portsunimi, bool saadaval, double portsuhind, int valuuta_ID)
        {
            MySqlDataReader reader = db.sendQuery("SELECT DISTINCT ports_ID FROM ports WHERE nimetus='" + portsunimi + "' AND saadaval=" + booleanToInt(saadaval) + " AND hind=" + portsuhind + " AND valuuta_ID=" + valuuta_ID);

            if (reader == null)
            {
                return -1;          //tekkis mingi viga
            }
            if (!reader.HasRows)
            {
                reader.Close();
                return 0;           //sellist kirjet ei leidu
            }

            int id;
            reader.Read();
            try
            {
                id = (int)reader.GetValue(0);
            }
            catch (Exception e)
            {
                Program.writeToLog("FAILED: getBatch(" + portsunimi + "," + saadaval + "," + portsuhind + "," + valuuta_ID + "): " + e.ToString());
                id = -1;
            }
            reader.Close();

            return id;
        }


        private int getEntitySoodustusId(Database db, string liik, double suurus, string yhik)
        {
            MySqlDataReader reader = db.sendQuery("SELECT DISTINCT soodustus_ID FROM soodustus WHERE liik='" + liik + "' AND suurus=" + suurus + " AND yhik='" + yhik + "'");

            if (reader == null)
            {
                Program.writeToLog("FAILED: getDiscount(" + liik + "," + suurus + "," + yhik + ")");
                return -1;          //tekkis mingi viga
            }
            if (!reader.HasRows)
            {
                reader.Close();
                return 0;           //sellist kirjet ei leidu
            }

            int id;
            reader.Read();
            try
            {
                id = (int)reader.GetValue(0);
            }
            catch (Exception e)
            {
                Program.writeToLog("FAILED: getDiscount(" + liik + "," + suurus + "," + yhik + "): " + e.ToString());
                id = -1;
            }
            reader.Close();

            return id;
        }


        private int getEntitySoodustusRidaId(Database db, int olemineID, int soodustusID)
        {
            MySqlDataReader reader = db.sendQuery("SELECT soodustus_rida_ID FROM soodustuse_rida WHERE olemine_ID=" + olemineID + " AND soodustus_ID=" + soodustusID);

            if (reader == null)
            {
                return -1;          //tekkis mingi viga
            }
            if (!reader.HasRows)
            {
                reader.Close();
                return 0;           //sellist kirjet ei leidu
            }

            int id;
            reader.Read();
            try
            {
                id = (int)reader.GetValue(0);
            }
            catch (Exception e)
            {
                Program.writeToLog("FAILED: getDiscountRow(" + olemineID + "," + soodustusID + "): " + e.ToString());
                id = -1;
            }
            reader.Close();

            return id;
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="db"></param>
        /// <param name="rowID">soodustuse rea ID, mida soovid muuta</param>
        /// <param name="olemine_ID">tabeli menyys_olemine väli olemine_ID</param>
        /// <param name="id">soodustuse ID, millega soovid menüüs olemist siduda</param>
        /// <returns></returns>
        private int updateEntitySoodustusRida(Database db, int rowID, int olemine_ID, int id)
        {
            String query = "UPDATE soodustuse_rida SET olemine_ID=" + olemine_ID + ",soodustus_ID=" + id + " WHERE soodustus_rida_ID=" + rowID;
            int affectedrows = db.sendNonQuery(query);
            if (affectedrows < 0)
            {
                Program.writeToLog("FAILED: updateDiscountRow(" + rowID + "," + olemine_ID + "," + id + ")");
            }

            return affectedrows;
        }


        private int removeFromSoodustuseRida(Database db, int olemineID, int soodustusID)
        {
            String query = "DELETE FROM soodustuse_rida WHERE olemine_ID=" + olemineID + " AND soodustus_ID=" + soodustusID;
            int rowsaffected = db.sendNonQuery(query);
            if (rowsaffected < 0)
            {
                Program.writeToLog("FAILED: removeFromSoodustuseRida(" + olemineID + "," + soodustusID + ")");
            }

            return rowsaffected;
        }


        private int insertCategory(Database db, string kategooria)
        {
            String query = "INSERT INTO kategooria(nimetus) VALUES(?nimetus)";
            MySqlParameter[] parameters = new MySqlParameter[1];
            parameters[0] = new MySqlParameter("?nimetus", kategooria);
            int lastInsertedUniqueId = db.parameterizedInsert(query, parameters);
            if (lastInsertedUniqueId < 1) {
                Program.writeToLog("FAILED: insertCategory(" + kategooria + ")");
            }
            else {
                Cache.setKategooriaListNull();
            }

            return lastInsertedUniqueId;
        }


        private int insertEntityKaup(Database db, int kohvikID, int kat_ID, string nimetus)
        {
            String query = "INSERT INTO kaup(kohvik_ID,kat_ID,nimetus) VALUES(?kohvik_ID,?kat_ID,?nimetus)";
            MySqlParameter[] parameters = new MySqlParameter[3];
            parameters[0] = new MySqlParameter("?kohvik_ID", kohvikID);
            parameters[1] = new MySqlParameter("?kat_ID", kat_ID);
            parameters[2] = new MySqlParameter("?nimetus", nimetus);
            int lastInsertedUniqueId = db.parameterizedInsert(query, parameters);
            if (lastInsertedUniqueId < 1)
                Program.writeToLog("FAILED: insertMerchandise(" + kohvikID + "," + kat_ID + "," + nimetus + ")");

            return lastInsertedUniqueId;
        }


        private int insertIntoMenu(Database db, int kaup_ID, string kuupaev)
        {
            String query = "INSERT INTO menyys_olemine(kaup_ID,kuupaev) VALUES(?kaup_ID,?kuupaev)";
            MySqlParameter[] parameters = new MySqlParameter[2];
            parameters[0] = new MySqlParameter("?kaup_ID", kaup_ID);
            parameters[1] = new MySqlParameter("?kuupaev", kuupaev);
            int lastInsertedUniqueId = db.parameterizedInsert(query, parameters);
            if (lastInsertedUniqueId < 1)
                Program.writeToLog("FAILED: insertIntoMenu(" + kaup_ID + "," + kuupaev + ")");

            return lastInsertedUniqueId;
        }


        private int removeFromMenu(Database db, int kaup_ID, string kuupaev)
        {
            String query = "DELETE FROM menyys_olemine WHERE kaup_ID=" + kaup_ID + " AND kuupaev='" + kuupaev + "'";
            int rowsaffected = db.sendNonQuery(query);
            if (rowsaffected < 0)
            {
                Program.writeToLog("FAILED: removeFromMenu(" + kaup_ID + "," + kuupaev + ")");
            }

            return rowsaffected;
        }


        private int insertEntityPorts(Database db, string portsunimi, bool saadaval, double portsuhind, int valuuta_ID)
        {
            String query = "INSERT INTO ports(nimetus,hind,valuuta_ID,saadaval) VALUES(?nimetus,?hind,?valuuta_ID,?saadaval)";
            MySqlParameter[] parameters = new MySqlParameter[4];
            parameters[0] = new MySqlParameter("?nimetus", portsunimi);
            parameters[1] = new MySqlParameter("?hind", portsuhind);
            parameters[2] = new MySqlParameter("?valuuta_ID", valuuta_ID);
            parameters[3] = new MySqlParameter("?saadaval", booleanToInt(saadaval));
            int lastInsertedUniqueId = db.parameterizedInsert(query, parameters);
            if (lastInsertedUniqueId < 1)
                Program.writeToLog("FAILED: insertBatch(" + portsunimi + "," + saadaval + "," + portsuhind + "," + valuuta_ID + ")");

            return lastInsertedUniqueId;
        }


        private int updateEntityPorts(Database db, int ports_ID, string portsunimi, bool saadaval, double portsuhind, int valuuta_ID)
        {
            String query = "UPDATE ports SET nimetus='" + portsunimi + "',saadaval=" + booleanToInt(saadaval) + ",hind=" + portsuhind + ",valuuta_ID=" + valuuta_ID + " WHERE ports_ID=" + ports_ID;
            int affectedrows = db.sendNonQuery(query);
            if (affectedrows < 0)
            {
                Program.writeToLog("FAILED: updateBatch(" + ports_ID + "," + portsunimi + "," + saadaval + "," + portsuhind + "," + valuuta_ID + ")");
            }

            return affectedrows;
        }


        private int deleteEntityPorts(Database db, int ports_ID)
        {
            String query = "DELETE FROM ports WHERE ports_ID=" + ports_ID;
            int rowsaffected = db.sendNonQuery(query);
            if (rowsaffected < 0)
            {
                Program.writeToLog("FAILED: deleteEntityPorts(" + ports_ID + ")");
            }

            return rowsaffected;
        }


        private int insertIntoPortsjonid(Database db, int olemine_ID, int ports_ID)
        {
            String query = "INSERT INTO portsjonid(olemine_ID,ports_ID) VALUES(" + olemine_ID + "," + ports_ID + ")";
            int affectedrows = db.sendNonQuery(query);
            if (affectedrows < 1)
                Program.writeToLog("FAILED: insertIntoBatches(" + olemine_ID + "," + ports_ID + ")");

            return affectedrows;
        }


        private int removeFromPortsud(Database db, int ports_ID)
        {
            String query = "DELETE FROM portsjonid WHERE ports_ID=" + ports_ID;
            int rowsaffected = db.sendNonQuery(query);
            if (rowsaffected < 0)
            {
                Program.writeToLog("FAILED: removeFromPortsud(" + ports_ID + ")");
            }

            return rowsaffected;
        }


        private int insertEntitySoodustus(Database db, string liik, double suurus, string yhik)
        {
            String query = "INSERT INTO soodustus(liik,suurus,yhik) VALUES(?liik,?suurus,?yhik)";
            MySqlParameter[] parameters = new MySqlParameter[3];
            parameters[0] = new MySqlParameter("?liik", liik);
            parameters[1] = new MySqlParameter("?suurus", suurus);
            parameters[2] = new MySqlParameter("?yhik", yhik);
            int lastInsertedUniqueId = db.parameterizedInsert(query, parameters);
            if (lastInsertedUniqueId < 0)
                Program.writeToLog("FAILED: insertDiscount(" + liik + "," + suurus + "," + yhik + ")");

            return lastInsertedUniqueId;
        }


        private int insertIntoSoodustuseRida(Database db, int olemine_ID, int soodustus_ID)
        {
            String query = "INSERT INTO soodustuse_rida(olemine_ID,soodustus_ID) VALUES(" + olemine_ID + "," + soodustus_ID + ")";
            int affectedrows = db.sendNonQuery(query);
            if (affectedrows < 1)
                Program.writeToLog("FAILED: insertIntoDiscounts(" + olemine_ID + "," + soodustus_ID + ")");

            return affectedrows;
        }


        public bool toggleAvailability(int ports_ID)
        {
            Database db = new Database();
            String query = "UPDATE ports SET saadaval=MOD(saadaval+1,2) WHERE ports_ID=" + ports_ID;
            int affectedrows = db.sendNonQuery(query);
            if (affectedrows < 1)
            {
                Program.writeToLog("FAILED: toggleAvailability(" + ports_ID + ")");
                return false;
            }

            return true;
        }
        #endregion


        #region uudised

        public bool deleteUudis(int uudisId)
        {
            int i = new Database().sendNonQuery("DELETE FROM uudised WHERE uudis_ID =" + uudisId);

            if (i != -1)
                return true;
            else
                return false;

        }


        /// <summary>
        /// Inserts new news to database
        /// </summary>
        /// <param name="uusUudis"></param>
        /// <returns></returns>
        public bool insertEntityUudis(EntityUudis uusUudis)
        {
            //parse values from input object
            int id = uusUudis.Kohvik_ID;
            string pealkiri = uusUudis.Pealkiri;
            string uudis = uusUudis.Uudis;
            
            //insert into database
            int i = new Database().sendNonQuery(string.Format("INSERT INTO uudised(kohvik_ID, pealkiri, uudis, aeg) VALUES ({0}, '{1}', '{2}', NOW())", id, pealkiri, uudis));

            if (i != -1)
                return true;
            else
                return false;
            
        }


        /// <summary>
        /// Replaces old news in database
        /// </summary>
        /// <param name="uusUudis"></param>
        /// <returns></returns>
        public bool editEntityUudis(EntityUudis uusUudis)
        {
            //parse values from input object
            int uudisId = uusUudis.uudisID;
            int id = uusUudis.Kohvik_ID;
            string pealkiri = uusUudis.Pealkiri;
            string uudis = uusUudis.Uudis;

            //update database
            
            int i = new Database().sendNonQuery(string.Format("UPDATE uudised SET kohvik_ID = {0}, pealkiri = '{1}', uudis = '{2}', aeg = '{3}' WHERE uudis_ID={4}", id, pealkiri, uudis, uusUudis.Aeg.ToString("yyyy-MM-dd"), uusUudis.uudisID));

            if (i != -1)
                return true;
            else
                return false;
        }



        /// <summary>
        /// Gets all news, sorted descending by date
        /// </summary>
        /// <returns></returns>
        public List<EntityUudis> getEntityUudisList()
        {
            Program.writeToLog("getEntityUudisList()");

            Database db = new Database();
            List<EntityUudis> uudised = new List<EntityUudis>();

            MySqlDataReader reader = db.sendQuery("SELECT t1.uudis_ID, t1.kohvik_ID, t1.pealkiri, t1.uudis, t1.aeg, t2.nimi FROM uudised t1, kohvik t2 WHERE t2.kohvik_ID=t1.kohvik_ID ORDER BY t1.aeg DESC");
            if (reader == null)
            {
                db.CloseConnection();
                return null;
            }

            if (!reader.HasRows)
            {
                reader.Close();
                db.CloseConnection();
                return null;
            }

            while (reader.Read())
            {
                uudised.Add(new EntityUudis()
                {
                    uudisID = (int)reader.GetValue(0),
                    Kohvik_ID = (int)reader.GetValue(1),
                    Pealkiri = (String)reader.GetValue(2),
                    Uudis = (String)reader.GetValue(3),
                    Aeg = (DateTime)reader.GetValue(4),
                    KohvikuNimi = (String)reader.GetValue(5)
                });
            }
            reader.Close();
            db.CloseConnection();

            return uudised;
        }


        /// <summary>
        /// Gets "limit" number of news, sorted descending by date
        /// </summary>
        /// <param name="limit"></param>
        /// <returns></returns>
        public List<EntityUudis> getEntityUudisListByAmount(int limit)
        {
            Program.writeToLog("getEntityUudisListByAmount(" + limit + ")");

            Database db = new Database();
            List<EntityUudis> uudised = new List<EntityUudis>();

            MySqlDataReader reader = db.sendQuery("SELECT t1.uudis_ID, t1.kohvik_ID, t1.pealkiri, t1.uudis, t1.aeg, t2.nimi FROM uudised t1, kohvik t2 WHERE t2.kohvik_ID=t1.kohvik_ID ORDER BY t1.aeg DESC LIMIT " + limit);
            if (reader == null)
            {
                db.CloseConnection();
                return null;
            }

            if (!reader.HasRows)
            {
                reader.Close();
                db.CloseConnection();
                return null;
            }

            while (reader.Read())
            {
                uudised.Add(new EntityUudis()
                {
                    uudisID = (int)reader.GetValue(0),
                    Kohvik_ID = (int)reader.GetValue(1),
                    Pealkiri = (String)reader.GetValue(2),
                    Uudis = (String)reader.GetValue(3),
                    Aeg = (DateTime)reader.GetValue(4),
                    KohvikuNimi = (String)reader.GetValue(5)
                });
            }
            reader.Close();
            db.CloseConnection();

            return uudised;
        }


        /// <summary>
        /// Gets the news with the given ID
        /// </summary>
        /// <param name="limit"></param>
        /// <returns></returns>
        public EntityUudis getEntityUudisById(int id)
        {
            Program.writeToLog("getEntityUudisById(" + id + ")");

            Database db = new Database();

            MySqlDataReader reader = db.sendQuery("SELECT t1.uudis_ID, t1.kohvik_ID, t1.pealkiri, t1.uudis, t1.aeg, t2.nimi FROM uudised t1, kohvik t2 WHERE t1.uudis_ID=" + id + " AND t2.kohvik_ID=t1.kohvik_ID");
            if (reader == null)
            {
                db.CloseConnection();
                return null;
            }

            if (reader.HasRows)
            {
                reader.Read();
            }
            else
            {
                reader.Close();
                db.CloseConnection();
                return null;
            }

            EntityUudis uudis = new EntityUudis
            {
                uudisID = (int)reader.GetValue(0),
                Kohvik_ID = (int)reader.GetValue(1),
                Pealkiri = (String)reader.GetValue(2),
                Uudis = (String)reader.GetValue(3),
                Aeg = (DateTime)reader.GetValue(4),
                KohvikuNimi = (String)reader.GetValue(5)
            };
            reader.Close();
            db.CloseConnection();

            return uudis;
        }
        #endregion


        #region LahtiolekuAjad
        public List<EntityLahtiolekuAjad> getEntityLahtiolekuAjadByKohvikId(int kohvikId)
        {
            Program.writeToLog("getEntityLahtiolekuAjadByKohvikId(" + kohvikId + ")");

            List<EntityLahtiolekuAjad> ajad = new List<EntityLahtiolekuAjad>();
            Database db = new Database();
            MySqlDataReader reader = db.sendQuery("select n.lyhend,l.avamisaeg,l.sulgemisaeg from nadalapaev n,lahti_olemine l where l.nadalapaev_ID=n.nadalapaev_ID and l.kohvik_ID=" + kohvikId);

            if (reader == null)
            {
                db.CloseConnection();
                return null;
            }

            if (!reader.HasRows)
            {
                reader.Close();
                db.CloseConnection();
                return null;
            }

            while (reader.Read())
            {
                ajad.Add(new EntityLahtiolekuAjad()
                {
                    Lyhend = (string)reader.GetValue(0),
                    Avamisaeg = (TimeSpan)reader.GetValue(1),
                    Sulgemisaeg = (TimeSpan)reader.GetValue(2)
                });
            }
            reader.Close();
            db.CloseConnection();

            return ajad;
        }
        #endregion


        #region Kommentaarid
        public List<EntityKommentaar> getEntityKommentaarList()
        {
            Program.writeToLog("getEntityKommentaarList()");

            Database db = new Database();
            List<EntityKommentaar> kommentaarid = new List<EntityKommentaar>();
            MySqlDataReader reader = db.sendQuery("SELECT * FROM kommentaar");

            if (reader == null)
            {
                db.CloseConnection();
                return null;
            }

            if (!reader.HasRows)
            {
                reader.Close();
                db.CloseConnection();
                return null;
            }

            while (reader.Read())
                kommentaarid.Add(new EntityKommentaar()
                {
                    Kommentaar_ID = (int)reader.GetValue(0),
                    Autor = (String)reader.GetValue(1),
                    Tekst = (String)reader.GetValue(2),
                    Aeg = (DateTime)reader.GetValue(3)
                });

            return kommentaarid;

        }


        public List<EntityKommentaar> getEntityKommentaarFor(KommentaarType kommentaarType, int id)
        {
            Program.writeToLog("getEntityKommentaarFor(" + kommentaarType + "," + id + ")");

            if (id < 1)
                return null;

            String tableName = "",
                query = "SELECT t1.autor, t1.tekst, t1.aeg FROM ",
                where = "";

            Database db = new Database();
            var kommentaarid = new List<EntityKommentaar>();


            switch (kommentaarType)
            {
                case KommentaarType.Kaup:
                    tableName = "kommentaar t1, kaup_kommentaar t2 ";
                    where = "WHERE t2.kaup_ID = " + id + " AND t2.kommentaar_ID = t1.kommentaar_ID";
                    break;
                case KommentaarType.Kohvik:
                    tableName = "kommentaar t1, kohvik_kommentaar t2 ";
                    where = "WHERE t2.kommentaar_ID = t1.kommentaar_ID AND t2.kohvik_ID =" + id;
                    break;
                default:
                    db.CloseConnection();
                    return null;
            }

            query += tableName;
            query += where;

            var reader = db.sendQuery(query);

            if (reader == null)
            {
                reader.Close();
                db.CloseConnection();
                return null;
            }

            if (!reader.HasRows)
            {
                reader.Close();
                db.CloseConnection();
                return null;
            }

            while (reader.Read())
                kommentaarid.Add(new EntityKommentaar()
                {
                    Autor = (String)reader.GetValue(0),
                    Tekst = (String)reader.GetValue(1),
                    Aeg = (DateTime)reader.GetValue(2)
                });

            return closeDbReaderAndReturn(kommentaarid, ref db, ref reader);
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <returns>-1 if invalid param, -2 if reader returns null (no result), else number of comments in db.</returns>
        public int getCommentCountFor(KommentaarType kommentaarType, int id)
        {
            Program.writeToLog("getCommentCountFor(" + kommentaarType + "," + id + ")");

            if (id < 1)
                return -1;

            int count = 0;

            String tableName = "",
                query = "",
                selectWhat = "",
                where = "";

            Database db = new Database();

            switch (kommentaarType)
            {
                case KommentaarType.Kaup:
                    tableName = "kaup_kommentaar ";
                    where = "WHERE kaup_ID = " + id.ToString();
                    selectWhat = "kaup_kom_ID";
                    break;
                case KommentaarType.Kohvik:
                    tableName = "kohvik_kommentaar ";
                    where = "WHERE kohvik_ID = " + id.ToString();
                    selectWhat = "kohvik_kom_ID";
                    break;
                default:
                    return closeDbAndReturn(-1, ref db);
            }

            query = "SELECT " + selectWhat + " FROM ";
            query += tableName;
            query += where;

            var reader = db.sendQuery(query);

            if (reader == null)
                return closeDbAndReturn(-2, ref db);

            if (!reader.HasRows)
            {
                return closeDbReaderAndReturn(count, ref db, ref reader);
            }

            while (reader.Read())
                ++count;

            return closeDbReaderAndReturn(count, ref db, ref reader);
        }


        /// <summary>
        /// </summary>
        /// <param name="kommentaarType">Millega kommentaar siduda</param>
        /// <param name="rowIdToAddKommentaarFor">Objekti rea unikaalne id, millega kommentaari siduda tahetakse</param>
        /// <param name="sisu">Kommentaari sisu</param>
        /// <param name="autor">Kommentaari autor</param>
        /// <param name="postituseAeg">Postituse aeg</param>
        /// <returns></returns>
        public bool addEntityKommentaarFor(KommentaarType kommentaarType, int rowIdToAddKommentaarFor, String sisu, String autor, DateTime postituseAeg)
        {
            Program.writeToLog("addKommentaarFor(" + kommentaarType + "," + rowIdToAddKommentaarFor + "," + sisu + "," + autor + "," + postituseAeg.ToString("yyyy-MM-dd") + ")");

            if (rowIdToAddKommentaarFor < 1)
                return false;

            Database db = new Database();

            String tableName = "",
                   idRowName = "",
                   query = "";

            switch (kommentaarType)
            {
                case KommentaarType.Kaup:
                    tableName = "kaup_kommentaar";
                    idRowName = "kaup_ID";
                    break;
                case KommentaarType.Kohvik:
                    tableName = "kohvik_kommentaar";
                    idRowName = "kohvik_ID";
                    break;
                default:
                    return closeDbAndReturn(false, ref db);

            }

            query = "INSERT INTO kommentaar(autor, tekst, aeg) VALUES(?autor, ?tekst, ?aeg)";
            MySqlParameter[] parameters = new MySqlParameter[3];
            parameters[0] = new MySqlParameter("?autor", autor);
            parameters[1] = new MySqlParameter("?tekst", sisu);
            parameters[2] = new MySqlParameter("?aeg", postituseAeg);
            int lastInsertedUniqueId = db.parameterizedInsert(query, parameters);   // Sisesta kommentaar, sebi sisestatud kommentaari ID.

            if (lastInsertedUniqueId < 1)
                return closeDbAndReturn(false, ref db);

            // Sisestame kommentaar-olemi seose valitud objekti vahel (kaup või kohvik)
            query = "INSERT INTO " + tableName + "(" + idRowName + ", kommentaar_ID) VALUES(" + rowIdToAddKommentaarFor + "," + lastInsertedUniqueId + ")";
            int rowsAffected = db.sendNonQuery(query);

            if (rowsAffected > 0)
                return closeDbAndReturn(true, ref db);
            else
                return closeDbAndReturn(false, ref db);
        }


        private T closeDbAndReturn<T>(T returnValue, ref Database db)
        {
            db.CloseConnection();

            return returnValue;
        }


        private T closeDbReaderAndReturn<T>(T returnValue, ref Database db, ref MySqlDataReader reader)
        {
            reader.Close();
            db.CloseConnection();

            return returnValue;
        }


        #endregion


        #region valuutad
        public List<EntityValuuta> getCurrency()
        {
            Program.writeToLog("getCurrency()");

            List<EntityValuuta> valuutad = Cache.getValuutaList();
            if (valuutad != null)
                return valuutad;

            valuutad = new List<EntityValuuta>();
            Database db = new Database();

            MySqlDataReader reader = db.sendQuery("SELECT * FROM valuuta");
            if (reader == null)
            {
                db.CloseConnection();
                return null;
            }

            if (!reader.HasRows)
            {
                reader.Close();
                db.CloseConnection();
                return null;
            }

            while (reader.Read())
            {
                valuutad.Add(new EntityValuuta
                {
                    Id = (int)reader.GetValue(0),
                    Lyhend = (String)reader.GetValue(1),
                    Nimetus = (String)reader.GetValue(2)
                });
            }
            reader.Close();

            db.CloseConnection();
            return valuutad;
        }
        #endregion


        #region krüpteering

        public string EncodePassword(string originalPassword)
        {
            Byte[] originalBytes;
            Byte[] encodedBytes;
            MD5 md5;

            // Conver the original password to bytes; then create the hash
            md5 = new MD5CryptoServiceProvider();
            originalBytes = ASCIIEncoding.Default.GetBytes(originalPassword);
            encodedBytes = md5.ComputeHash(originalBytes);

            // Bytes to string
            string kood = BitConverter.ToString(encodedBytes);
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < kood.Length; i++)
            {
                if (char.IsLetterOrDigit(kood[i]))
                {
                    sb.Append(kood[i]);
                }
            }

            return sb.ToString().ToLower();
        }
        #endregion


        #region autocomplete
        /// <summary>
        /// tagastab kategooriate nimed, mis algavad soovitud stringiga
        /// </summary>
        /// <param name="prefixText"></param>
        /// <returns></returns>
        public List<String> getKatNimed(string prefixText)
        {
            Program.writeToLog("getKatNimed(" + prefixText + ")");

            List<EntityKategooria> kategooriad = getAllCategories();
            if (kategooriad == null)
                return null;

            List<String> ss = new List<String>();
            prefixText = prefixText.ToLower();
            foreach (EntityKategooria kat in kategooriad) {
                if (kat.Nimetus.ToLower().StartsWith(prefixText)) {
                    ss.Add(kat.Nimetus);
                }
            }
            return ss;
        }


        /// <summary>
        /// tagastab kaupade nimed, mis algavad soovitud stringiga ja kuuluvad soovitud kohvikule
        /// </summary>
        /// <param name="kohvikID"></param>
        /// <param name="prefixText"></param>
        /// <returns></returns>
        public List<String> getKaupNimed(int kohvikID, String prefixText)
        {
            Program.writeToLog("getKaupNimed(" + kohvikID + "," + prefixText + ")");

            List<String> ss = new List<String>();
            
            List<EntityKaup> kaubad = getAllItemNames();
            if(kaubad == null)
                return null;

            prefixText = prefixText.ToLower();
            foreach (EntityKaup s in kaubad)
            {
                if (s.KohvikID == kohvikID) { 
                    if (s.Nimetus.ToLower().StartsWith(prefixText))
                    {
                        ss.Add(s.Nimetus);
                    }
                }
            }
            return ss;
        }
        #endregion


        #region login
        public Boolean isSuperAdmin(string kasutajaId)
        {
            Boolean result = false;

            MySqlDataReader dr = new Database().sendQuery("SELECT roll_ID FROM kasutaja_rollis WHERE kasutaja_rollis.kasutaja_ID = " + kasutajaId);

            dr.Read();

            if (dr["roll_ID"].ToString() == "2")
                result = true;

            dr.Close();

            return result;
        }



        public int login(String user, String pass)
        {
            char[] SpecialChars = "=<>!@#$%^&*()".ToCharArray();

            int indexOfUser = user.IndexOfAny(SpecialChars);
            int indexOfPass = pass.IndexOfAny(SpecialChars);

            if (indexOfUser == -1 && indexOfPass == -1)
            {

                Database db = new Database();

                MySqlDataReader reader = db.sendQuery("SELECT kasutaja_ID FROM kasutaja where kasutajanimi='" + user + "' and parool='" + pass + "'");
                if (reader == null)
                {
                    db.CloseConnection();
                    return 0;
                }

                if (!reader.HasRows)
                {
                    reader.Close();
                    db.CloseConnection();
                    return 0;
                }

                int kasutaja_ID = 0;
                reader.Read();
                kasutaja_ID = (int)reader.GetValue(0);

                reader.Close();
                db.CloseConnection();
                return kasutaja_ID;

            } //end if
            else return 0;

        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <returns>kohviku ID. Kui päring ei õnnestu, siis -1, kui on tegemist administraatoriga, siis 0.</returns>
        public int getCafIdByUserId(int id)
        {
            Database db = new Database();

            MySqlDataReader reader = db.sendQuery("SELECT kohvik_ID FROM kasutaja_rollis WHERE kasutaja_ID=" + id);
            if (reader == null)
            {
                db.CloseConnection();
                return -1;
            }

            if (!reader.HasRows)
            {
                reader.Close();
                db.CloseConnection();
                return -1;
            }

            int cafID = 0;
            reader.Read();
            try
            {
                cafID = (int)reader.GetValue(0);
            }
            catch (Exception)
            {
                return -1;
            }

            reader.Close();
            db.CloseConnection();

            return cafID;
        }


        public int getUserRoleId(int userID)
        {
            Database db = new Database();

            MySqlDataReader reader = db.sendQuery("SELECT roll_ID FROM kasutaja_rollis WHERE kasutaja_ID=" + userID);
            if (reader == null)
            {
                db.CloseConnection();
                return -1;
            }

            if (!reader.HasRows)
            {
                reader.Close();
                db.CloseConnection();
                return -1;
            }

            int roleID;
            reader.Read();
            try
            {
                roleID = (int)reader.GetValue(0);
            }
            catch (Exception)
            {
                return -1;
            }

            reader.Close();
            db.CloseConnection();

            return roleID;
        }
        #endregion


        #region abimeetodid
        private Boolean intToBoolean(int i)
        {
            if (i == 1)
            {
                return true;
            }
            else
            {
                return false;
            }
        }


        private int booleanToInt(bool b)
        {
            if (b)
            {
                return 1;
            }
            else
            {
                return 0;
            }
        }
        #endregion

                
    }   //END class
}       //END namespace
